package com.jacob.androidframe.base;

import org.androidannotations.annotations.AfterInject;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EActivity;

import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.widget.Toast;

/**
 * 本类是所有Activity的父类。
 * 用来封装和业务无关的复杂代码（例如显示消息、弹出对话框、启动其他Activity等），简化Activity的代码量。
 * 
 * @author 王超
 */
@EActivity
public abstract class ActivityBase extends FragmentActivity
{
	/** Start of user-defined activity requests. */
    public static final int REQUEST_FIRST_USER = 1;
    
	private Toast	mToast;

	/**
	 * 这个方法必须实现。系统创建Activity时，调用这个方法。
	 * 本方法中，一般应该初始化Activity的必要组件，执行全局状态的设置。
	 * 如：初始化成员变量、初始化Fragment、初始化Loader、创建View、绑定数据到List、创建线程等。
	 * 最重要的是，方法里必须调用setContentView()来定义Activity的用户界面使用的Layout。
	 * 下一个生命周期回调方法：onStart()。
	 * 
	 * @param pSavedInstanceState
	 *            如果Activity先前被销毁，现在要重新创建。那么这个参数就含有状态信息。否则为null。
	 */
	@Override
	protected void onCreate(Bundle pSavedInstanceState)
	{
		super.onCreate(pSavedInstanceState);
	}

	/**
	 * Activity被停止后（系统调用了onStop()方法），若其被销毁前，再次回到前台，
	 * 则系统调用先本方法，然后接着调用onStart()和onResume()。
	 * 下一个生命周期回调方法：onStart()。
	 */
	@Override
	protected void onRestart()
	{
		super.onRestart();
	}

	/**
	 * Activity变成用户可见的后，系统立即调用本方法。
	 * 本方法中，应该
	 * 如：绑定Service，注册BroadcastReceiver，启动线程等。
	 * 下一个生命周期回调方法：
	 * 1. 若Activity下面要显示到前台，同时不需要恢复状态，则接下来调用onResume()方法。
	 * 2. 若Activity下面要显示到前台，同时需要恢复状态，则接下来调用onRestoreInstanceState()方法。
	 * 3. 若Activity下面要隐藏，则跟着调用onStop()方法。
	 */
	@Override
	protected void onStart()
	{
		super.onStart();
	}

	/**
	 * 当Activity先前被销毁，要重新创建时，系统会把pSavedInstanceState参数同时传给onCreate()方法和本方法。
	 * 在大多数情况下，在onCreate()方法中恢复Activity状态即可，但是有时候需要允许子类来决定是否使用父类的恢复方法。
	 * 此时可以在onCreate()方法中进行一般初始化，将恢复步骤放在本方法中。
	 * 下一个生命周期回调方法：onResume()。
	 * 
	 * @param pSavedInstanceState
	 *            如果Activity先前被销毁，现在要重新创建。那么这个参数就含有状态信息。否则为null。
	 */
	@Override
	protected void onRestoreInstanceState(Bundle pSavedInstanceState)
	{
		super.onRestoreInstanceState(pSavedInstanceState);
	}

	/**
	 * Activity开始和用户交互后，系统立即调用本方法。
	 * 此时Activity在Back Stack栈的顶端，拥有用户输入的焦点。
	 * 本方法中的代码应该是十分轻量级的，以避免造成用户等待。
	 * 下一个生命周期回调方法：
	 * 1. 若Activity变成隐藏的，但并不销毁，则接下来调用onPause()方法。
	 * 2. 若Activity变成隐藏的，同时要销毁，则接下来调用onPause()方法或者onSaveInstanceState()方法。
	 */
	@Override
	protected void onResume()
	{
		super.onResume();
	}

	/**
	 * 用户离开Activity时（这并不总是意味着Activity被销毁了），系统第一个调用本方法。
	 * 本方法中，应该提交当前用户会话所做的修改，停止动画、和消耗CPU的操作等等（因为用户可能不会回来了）。
	 * 本方法中的代码应该是十分轻量级的，以避免造成用户等待。
	 * 这里无论要做什么，都应该很快的做完。因为本方法不返回，下一个Activity是无法恢复的。
	 * 下一个生命周期回调方法：
	 * 1. 若Activity返回到前台，则接下来调用onResume()方法；
	 * 2. 若Activity变成隐藏的，但并不销毁，则接下来调用onStop()方法。
	 */
	@Override
	protected void onPause()
	{
		super.onPause();
	}

	/**
	 * 系统在销毁Activity前，会调用本方法。
	 * 系统向这个方法传入Bundle对象，可以使用这个对象保存Activity的状态信息。
	 * 调用类似putString()和putInt()之类的方法，以键值对的形式保存信息。
	 * 注意：Activity被销毁前，无法保证onSaveInstanceState()方法一定会被调用，因为存在没有必要保存状态的情况（比如当用户使用返回键离开Activity时，因为用户的意图就是关闭Activity）。
	 * 如果系统需要调用onSaveInstanceState()方法，则会在onStop()方法之前调用，但可能在onPause()方法之前，也可能在onPause()方法之后。
	 * 为了简化理解，可以认为当Activity需要被保存状态时，本方法和onPause()方法同时被调用，然后再调用onStop()方法。
	 * 下一个生命周期回调方法：onStop()方法。
	 * 
	 * @param pOutState
	 *            用来存放Activity状态信息的Bundle对象
	 */
	@Override
	protected void onSaveInstanceState(Bundle pOutState)
	{
		super.onSaveInstanceState(pOutState);
	}

	/**
	 * 当Activity对用户不再可见时，系统调用本方法。
	 * 本方法中，应该
	 * 如：取消Service绑定，反注册BroadcastReceiver，停止线程，停止动画，停止监听器和定时器等。
	 * 下一个生命周期回调方法：
	 * 1. 如果Activity又返回和用户交互，后面跟着调用onRestart()方法。
	 * 2. 如果Activity要被销毁，后面调用onDestroy()方法。
	 */
	@Override
	protected void onStop()
	{
		super.onStop();
	}

	/**
	 * Activity被销毁前，系统调用本方法。这是Activity将接收到的最后一个调用。
	 * 系统调用这个方法，要么是因为Activity自己完成了（有人调用了Activity的finish()方法），要么是因为系统要销毁这个Activity对象以释放空间。
	 * 可以通过isFinishing()方法区分这两种情况。
	 * 本方法中，应该释放全部的保留资源。
	 * 如：停止线程等。
	 */
	@Override
	protected void onDestroy()
	{
		super.onDestroy();
	}

	/**
	 * 当使用startActivityForResult()方法启动的另一个Activity退出时，系统调用本方法。
	 * 调用顺序是，当Activity重新启动时，紧接着onResume()前。
	 * 本方法的一般逻辑为：
	 * 1.检查请求是否是已知的，pRequestCode是否等于传入startActivityForResult()方法的第二个参数。
	 * 2.检查结果是否成功，若结果成功，pResultCode就会是RESULT_OK。
	 * 3.查询返回的Intent（pData参数）中的数据，进行处理结果。
	 * 
	 * @param pRequestCode
	 *            由startActivityForResult()方法传入的，使用这个值判断本次结果来自哪个请求。
	 * @param pResultCode
	 *            由被启动的Activity.setResult()方法传入的，这个值共有3种，分别是{@link #RESULT_OK}、{@link #RESULT_CANCELED}和用户自定义的值（{@link #RESULT_FIRST_USER}+x）。若被启动的Activity没有设置这个值，或者其在执行过程中崩溃，则这个值会是
	 *            {@link #RESULT_CANCELED}。
	 * @param pData
	 *            Intent对象，其中含有返回结果的数据。
	 */
	@Override
	protected void onActivityResult(int pRequestCode, int pResultCode, Intent pData)
	{
		super.onActivityResult(pRequestCode, pResultCode, pData);
	}
	
	/**
	 * 用较短时间显示Toast消息
	 * 
	 * @param pMsg
	 *            消息内容
	 */
	protected void showToastShort(String pMsg)
	{
		if (pMsg != null) {
			if (mToast == null) {
				mToast = Toast.makeText(this, pMsg, Toast.LENGTH_SHORT);
			} else {
				mToast.setText(pMsg);
				mToast.setDuration(Toast.LENGTH_SHORT);
			}
			mToast.show();
		}
	}

	/**
	 * 用较短时间显示Toast消息
	 * 
	 * @param pStringResId
	 *            String资源ID
	 */
	protected void showToastShort(int pStringResId)
	{
		String _MsgString = getString(pStringResId);
		showToastShort(_MsgString);
	}

	/**
	 * 用较长时间显示Toast消息
	 * 
	 * @param pMsg
	 *            消息内容
	 */
	protected void showToastLong(String pMsg)
	{
		if (pMsg != null) {
			if (mToast == null) {
				mToast = Toast.makeText(this, pMsg, Toast.LENGTH_LONG);
			} else {
				mToast.setText(pMsg);
				mToast.setDuration(Toast.LENGTH_LONG);
			}
			mToast.show();
		}
	}

	/**
	 * 用较长时间显示Toast消息
	 * 
	 * @param pStringResId
	 *            String资源ID
	 */
	protected void showToastLong(int pStringResId)
	{
		String _MsgString = getString(pStringResId);
		showToastLong(_MsgString);
	}

	@AfterInject
	protected abstract void afterInject();
	
	protected abstract void initOnCreate(Bundle pSavedInstanceState);
	
	@AfterViews
	protected abstract void afterView();

}
